1   /*
2    * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  /* $Id: Rijndael.java,v 1.6 2000/02/10 01:31:41 gelderen Exp $
27   *
28   * Copyright (C) 1995-2000 The Cryptix Foundation Limited.
29   * All rights reserved.
30   *
31   * Use, modification, copying and distribution of this softwareas is subject
32   * the terms and conditions of the Cryptix General Licence. You should have
33   * received a copy of the Cryptix General Licence along with this library;
34   * if not, you can download a copy from http://www.cryptix.org/ .
35   */
36  
37  package com.sun.crypto.provider;
38  
39  import java.security.InvalidKeyException;
40  
41  /**
42   * Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit
43   * block size and variable key-size (128-, 192- and 256-bit).
44   * <p>
45   * Rijndael was designed by <a href="mailto:rijmen@esat.kuleuven.ac.be">Vincent
46   * Rijmen</a> and <a href="mailto:Joan.Daemen@village.uunet.be">Joan Daemen</a>.
47   */
48  final class AESCrypt extends SymmetricCipher implements AESConstants
49  {
50      private boolean ROUNDS_12 = false;
51      private boolean ROUNDS_14 = false;
52  
53      /** Session and Sub keys */
54      private Object[] sessionK = null;
55      private int[] K = null;
56  
57      /** (ROUNDS-1) * 4 */
58      private int limit = 0;
59  
60      AESCrypt() {
61          // empty
62      }
63  
64      /**
65       * Returns this cipher's block size.
66       *
67       * @return this cipher's block size
68       */
69      int getBlockSize() {
70          return AES_BLOCK_SIZE;
71      }
72  
73      void init(boolean decrypting, String algorithm, byte[] key)
74              throws InvalidKeyException {
75          if (!algorithm.equalsIgnoreCase("AES")
76                      && !algorithm.equalsIgnoreCase("Rijndael")) {
77              throw new InvalidKeyException
78                  ("Wrong algorithm: AES or Rijndael required");
79          }
80          if (!isKeySizeValid(key.length)) {
81              throw new InvalidKeyException("Invalid AES key length: " +
82                  key.length + " bytes");
83          }
84  
85          // generate session key and reset sub key.
86          sessionK = makeKey(key);
87          setSubKey(decrypting);
88      }
89  
90      private void setSubKey(boolean decrypting) {
91          int[][] Kd = (int[][]) sessionK[decrypting ? 1 : 0];
92          int rounds = Kd.length;
93          this.K = new int[rounds*4];
94          for(int i=0; i<rounds; i++) {
95              for(int j=0; j<4; j++) {
96                  K[i*4 + j] = Kd[i][j];
97              }
98          }
99  
100         if (decrypting) {
101             int j0 = K[K.length-4];
102             int j1 = K[K.length-3];
103             int j2 = K[K.length-2];
104             int j3 = K[K.length-1];
105 
106             for (int i=this.K.length-1; i>3; i--) {
107                 this.K[i] = this.K[i-4];
108             }
109             K[0] = j0;
110             K[1] = j1;
111             K[2] = j2;
112             K[3] = j3;
113         }
114 
115         ROUNDS_12 = (rounds>=13);
116         ROUNDS_14 = (rounds==15);
117 
118         rounds--;
119         limit=rounds*4;
120     }
121 
122     private static int[]
123         alog = new int[256],
124         log  = new int[256];
125 
126     private static final byte[]
127         S  = new byte[256],
128         Si = new byte[256];
129 
130     private static final int[]
131         T1 = new int[256],
132         T2 = new int[256],
133         T3 = new int[256],
134         T4 = new int[256],
135         T5 = new int[256],
136         T6 = new int[256],
137         T7 = new int[256],
138         T8 = new int[256];
139 
140     private static final int[]
141         U1 = new int[256],
142         U2 = new int[256],
143         U3 = new int[256],
144         U4 = new int[256];
145 
146     private static final byte[] rcon = new byte[30];
147 
148 
149     // Static code - to intialise S-boxes and T-boxes
150     static
151     {
152         int ROOT = 0x11B;
153         int i, j = 0;
154 
155         //
156         // produce log and alog tables, needed for multiplying in the
157         // field GF(2^m) (generator = 3)
158         //
159         alog[0] = 1;
160         for (i = 1; i < 256; i++)
161         {
162             j = (alog[i-1] << 1) ^ alog[i-1];
163             if ((j & 0x100) != 0) {
164                 j ^= ROOT;
165             }
166             alog[i] = j;
167         }
168         for (i = 1; i < 255; i++) {
169             log[alog[i]] = i;
170         }
171         byte[][] A = new byte[][]
172         {
173             {1, 1, 1, 1, 1, 0, 0, 0},
174             {0, 1, 1, 1, 1, 1, 0, 0},
175             {0, 0, 1, 1, 1, 1, 1, 0},
176             {0, 0, 0, 1, 1, 1, 1, 1},
177             {1, 0, 0, 0, 1, 1, 1, 1},
178             {1, 1, 0, 0, 0, 1, 1, 1},
179             {1, 1, 1, 0, 0, 0, 1, 1},
180             {1, 1, 1, 1, 0, 0, 0, 1}
181         };
182         byte[] B = new byte[] { 0, 1, 1, 0, 0, 0, 1, 1};
183 
184         //
185         // substitution box based on F^{-1}(x)
186         //
187         int t;
188         byte[][] box = new byte[256][8];
189         box[1][7] = 1;
190         for (i = 2; i < 256; i++) {
191             j = alog[255 - log[i]];
192             for (t = 0; t < 8; t++) {
193                 box[i][t] = (byte)((j >>> (7 - t)) & 0x01);
194             }
195         }
196         //
197         // affine transform:  box[i] <- B + A*box[i]
198         //
199         byte[][] cox = new byte[256][8];
200         for (i = 0; i < 256; i++) {
201             for (t = 0; t < 8; t++) {
202                 cox[i][t] = B[t];
203                 for (j = 0; j < 8; j++) {
204                     cox[i][t] ^= A[t][j] * box[i][j];
205                 }
206             }
207         }
208         //
209         // S-boxes and inverse S-boxes
210         //
211         for (i = 0; i < 256; i++) {
212             S[i] = (byte)(cox[i][0] << 7);
213             for (t = 1; t < 8; t++) {
214                     S[i] ^= cox[i][t] << (7-t);
215             }
216             Si[S[i] & 0xFF] = (byte) i;
217         }
218         //
219         // T-boxes
220         //
221         byte[][] G = new byte[][] {
222             {2, 1, 1, 3},
223             {3, 2, 1, 1},
224             {1, 3, 2, 1},
225             {1, 1, 3, 2}
226         };
227         byte[][] AA = new byte[4][8];
228         for (i = 0; i < 4; i++) {
229             for (j = 0; j < 4; j++) AA[i][j] = G[i][j];
230             AA[i][i+4] = 1;
231         }
232         byte pivot, tmp;
233         byte[][] iG = new byte[4][4];
234         for (i = 0; i < 4; i++) {
235             pivot = AA[i][i];
236             if (pivot == 0) {
237                 t = i + 1;
238                 while ((AA[t][i] == 0) && (t < 4)) {
239                     t++;
240                 }
241                 if (t == 4) {
242                     throw new RuntimeException("G matrix is not invertible");
243                 }
244                 else {
245                     for (j = 0; j < 8; j++) {
246                         tmp = AA[i][j];
247                         AA[i][j] = AA[t][j];
248                         AA[t][j] = (byte) tmp;
249                     }
250                     pivot = AA[i][i];
251                 }
252             }
253             for (j = 0; j < 8; j++) {
254                 if (AA[i][j] != 0) {
255                     AA[i][j] = (byte)
256                         alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF])
257                         % 255];
258                 }
259             }
260             for (t = 0; t < 4; t++) {
261                 if (i != t) {
262                     for (j = i+1; j < 8; j++) {
263                         AA[t][j] ^= mul(AA[i][j], AA[t][i]);
264                     }
265                     AA[t][i] = 0;
266                 }
267             }
268         }
269         for (i = 0; i < 4; i++) {
270             for (j = 0; j < 4; j++) {
271                 iG[i][j] = AA[i][j + 4];
272             }
273         }
274 
275         int s;
276         for (t = 0; t < 256; t++) {
277             s = S[t];
278             T1[t] = mul4(s, G[0]);
279             T2[t] = mul4(s, G[1]);
280             T3[t] = mul4(s, G[2]);
281             T4[t] = mul4(s, G[3]);
282 
283             s = Si[t];
284             T5[t] = mul4(s, iG[0]);
285             T6[t] = mul4(s, iG[1]);
286             T7[t] = mul4(s, iG[2]);
287             T8[t] = mul4(s, iG[3]);
288 
289             U1[t] = mul4(t, iG[0]);
290             U2[t] = mul4(t, iG[1]);
291             U3[t] = mul4(t, iG[2]);
292             U4[t] = mul4(t, iG[3]);
293         }
294         //
295         // round constants
296         //
297         rcon[0] = 1;
298         int r = 1;
299         for (t = 1; t < 30; t++) {
300             r = mul(2, r);
301             rcon[t] = (byte) r;
302         }
303         log = null;
304         alog = null;
305     }
306 
307     // multiply two elements of GF(2^m)
308     private static final int mul (int a, int b) {
309         return (a != 0 && b != 0) ?
310             alog[(log[a & 0xFF] + log[b & 0xFF]) % 255] :
311             0;
312     }
313 
314     // convenience method used in generating Transposition boxes
315     private static final int mul4 (int a, byte[] b) {
316         if (a == 0) return 0;
317         a = log[a & 0xFF];
318         int a0 = (b[0] != 0) ? alog[(a + log[b[0] & 0xFF]) % 255] & 0xFF : 0;
319         int a1 = (b[1] != 0) ? alog[(a + log[b[1] & 0xFF]) % 255] & 0xFF : 0;
320         int a2 = (b[2] != 0) ? alog[(a + log[b[2] & 0xFF]) % 255] & 0xFF : 0;
321         int a3 = (b[3] != 0) ? alog[(a + log[b[3] & 0xFF]) % 255] & 0xFF : 0;
322         return a0 << 24 | a1 << 16 | a2 << 8 | a3;
323     }
324 
325     // check if the specified length (in bytes) is a valid keysize for AES
326     static final boolean isKeySizeValid(int len) {
327         for (int i = 0; i < AES_KEYSIZES.length; i++) {
328             if (len == AES_KEYSIZES[i]) {
329                 return true;
330             }
331         }
332         return false;
333     }
334 
335     /**
336      * Encrypt exactly one block of plaintext.
337      */
338     void encryptBlock(byte[] in, int inOffset,
339                               byte[] out, int outOffset)
340     {
341         int keyOffset = 0;
342         int t0   = ((in[inOffset++]       ) << 24 |
343                     (in[inOffset++] & 0xFF) << 16 |
344                     (in[inOffset++] & 0xFF) <<  8 |
345                     (in[inOffset++] & 0xFF)        ) ^ K[keyOffset++];
346         int t1   = ((in[inOffset++]       ) << 24 |
347                     (in[inOffset++] & 0xFF) << 16 |
348                     (in[inOffset++] & 0xFF) <<  8 |
349                     (in[inOffset++] & 0xFF)        ) ^ K[keyOffset++];
350         int t2   = ((in[inOffset++]       ) << 24 |
351                     (in[inOffset++] & 0xFF) << 16 |
352                     (in[inOffset++] & 0xFF) <<  8 |
353                     (in[inOffset++] & 0xFF)        ) ^ K[keyOffset++];
354         int t3   = ((in[inOffset++]       ) << 24 |
355                     (in[inOffset++] & 0xFF) << 16 |
356                     (in[inOffset++] & 0xFF) <<  8 |
357                     (in[inOffset++] & 0xFF)        ) ^ K[keyOffset++];
358 
359         // apply round transforms
360         while( keyOffset < limit )
361         {
362             int a0, a1, a2;
363             a0 = T1[(t0 >>> 24)       ] ^
364                  T2[(t1 >>> 16) & 0xFF] ^
365                  T3[(t2 >>>  8) & 0xFF] ^
366                  T4[(t3       ) & 0xFF] ^ K[keyOffset++];
367             a1 = T1[(t1 >>> 24)       ] ^
368                  T2[(t2 >>> 16) & 0xFF] ^
369                  T3[(t3 >>>  8) & 0xFF] ^
370                  T4[(t0       ) & 0xFF] ^ K[keyOffset++];
371             a2 = T1[(t2 >>> 24)       ] ^
372                  T2[(t3 >>> 16) & 0xFF] ^
373                  T3[(t0 >>>  8) & 0xFF] ^
374                  T4[(t1       ) & 0xFF] ^ K[keyOffset++];
375             t3 = T1[(t3 >>> 24)       ] ^
376                  T2[(t0 >>> 16) & 0xFF] ^
377                  T3[(t1 >>>  8) & 0xFF] ^
378                  T4[(t2       ) & 0xFF] ^ K[keyOffset++];
379             t0 = a0; t1 = a1; t2 = a2;
380         }
381 
382         // last round is special
383         int tt = K[keyOffset++];
384         out[outOffset++] = (byte)(S[(t0 >>> 24)       ] ^ (tt >>> 24));
385         out[outOffset++] = (byte)(S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
386         out[outOffset++] = (byte)(S[(t2 >>>  8) & 0xFF] ^ (tt >>>  8));
387         out[outOffset++] = (byte)(S[(t3       ) & 0xFF] ^ (tt       ));
388         tt = K[keyOffset++];
389         out[outOffset++] = (byte)(S[(t1 >>> 24)       ] ^ (tt >>> 24));
390         out[outOffset++] = (byte)(S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
391         out[outOffset++] = (byte)(S[(t3 >>>  8) & 0xFF] ^ (tt >>>  8));
392         out[outOffset++] = (byte)(S[(t0       ) & 0xFF] ^ (tt       ));
393         tt = K[keyOffset++];
394         out[outOffset++] = (byte)(S[(t2 >>> 24)       ] ^ (tt >>> 24));
395         out[outOffset++] = (byte)(S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
396         out[outOffset++] = (byte)(S[(t0 >>>  8) & 0xFF] ^ (tt >>>  8));
397         out[outOffset++] = (byte)(S[(t1       ) & 0xFF] ^ (tt       ));
398         tt = K[keyOffset++];
399         out[outOffset++] = (byte)(S[(t3 >>> 24)       ] ^ (tt >>> 24));
400         out[outOffset++] = (byte)(S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
401         out[outOffset++] = (byte)(S[(t1 >>>  8) & 0xFF] ^ (tt >>>  8));
402         out[outOffset  ] = (byte)(S[(t2       ) & 0xFF] ^ (tt       ));
403     }
404 
405 
406     /**
407      * Decrypt exactly one block of plaintext.
408      */
409     void decryptBlock(byte[] in, int inOffset,
410                               byte[] out, int outOffset)
411     {
412         int keyOffset = 4;
413         int t0 = ((in[inOffset++]       ) << 24 |
414                   (in[inOffset++] & 0xFF) << 16 |
415                   (in[inOffset++] & 0xFF) <<  8 |
416                   (in[inOffset++] & 0xFF)        ) ^ K[keyOffset++];
417         int t1 = ((in[inOffset++]       ) << 24 |
418                   (in[inOffset++] & 0xFF) << 16 |
419                   (in[inOffset++] & 0xFF) <<  8 |
420                   (in[inOffset++] & 0xFF)        ) ^ K[keyOffset++];
421         int t2 = ((in[inOffset++]       ) << 24 |
422                   (in[inOffset++] & 0xFF) << 16 |
423                   (in[inOffset++] & 0xFF) <<  8 |
424                   (in[inOffset++] & 0xFF)        ) ^ K[keyOffset++];
425         int t3 = ((in[inOffset++]       ) << 24 |
426                   (in[inOffset++] & 0xFF) << 16 |
427                   (in[inOffset++] & 0xFF) <<  8 |
428                   (in[inOffset  ] & 0xFF)        ) ^ K[keyOffset++];
429 
430         int a0, a1, a2;
431         if(ROUNDS_12)
432         {
433             a0 = T5[(t0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
434                  T7[(t2>>> 8)&0xFF] ^ T8[(t1     )&0xFF] ^ K[keyOffset++];
435             a1 = T5[(t1>>>24)     ] ^ T6[(t0>>>16)&0xFF] ^
436                  T7[(t3>>> 8)&0xFF] ^ T8[(t2     )&0xFF] ^ K[keyOffset++];
437             a2 = T5[(t2>>>24)     ] ^ T6[(t1>>>16)&0xFF] ^
438                  T7[(t0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
439             t3 = T5[(t3>>>24)     ] ^ T6[(t2>>>16)&0xFF] ^
440                  T7[(t1>>> 8)&0xFF] ^ T8[(t0     )&0xFF] ^ K[keyOffset++];
441             t0 = T5[(a0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
442                  T7[(a2>>> 8)&0xFF] ^ T8[(a1     )&0xFF] ^ K[keyOffset++];
443             t1 = T5[(a1>>>24)     ] ^ T6[(a0>>>16)&0xFF] ^
444                  T7[(t3>>> 8)&0xFF] ^ T8[(a2     )&0xFF] ^ K[keyOffset++];
445             t2 = T5[(a2>>>24)     ] ^ T6[(a1>>>16)&0xFF] ^
446                  T7[(a0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
447             t3 = T5[(t3>>>24)     ] ^ T6[(a2>>>16)&0xFF] ^
448                  T7[(a1>>> 8)&0xFF] ^ T8[(a0     )&0xFF] ^ K[keyOffset++];
449 
450             if(ROUNDS_14)
451             {
452                 a0 = T5[(t0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
453                      T7[(t2>>> 8)&0xFF] ^ T8[(t1     )&0xFF] ^ K[keyOffset++];
454                 a1 = T5[(t1>>>24)     ] ^ T6[(t0>>>16)&0xFF] ^
455                      T7[(t3>>> 8)&0xFF] ^ T8[(t2     )&0xFF] ^ K[keyOffset++];
456                 a2 = T5[(t2>>>24)     ] ^ T6[(t1>>>16)&0xFF] ^
457                      T7[(t0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
458                 t3 = T5[(t3>>>24)     ] ^ T6[(t2>>>16)&0xFF] ^
459                      T7[(t1>>> 8)&0xFF] ^ T8[(t0     )&0xFF] ^ K[keyOffset++];
460                 t0 = T5[(a0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
461                      T7[(a2>>> 8)&0xFF] ^ T8[(a1     )&0xFF] ^ K[keyOffset++];
462                 t1 = T5[(a1>>>24)     ] ^ T6[(a0>>>16)&0xFF] ^
463                      T7[(t3>>> 8)&0xFF] ^ T8[(a2     )&0xFF] ^ K[keyOffset++];
464                 t2 = T5[(a2>>>24)     ] ^ T6[(a1>>>16)&0xFF] ^
465                      T7[(a0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
466                 t3 = T5[(t3>>>24)     ] ^ T6[(a2>>>16)&0xFF] ^
467                      T7[(a1>>> 8)&0xFF] ^ T8[(a0     )&0xFF] ^ K[keyOffset++];
468             }
469         }
470         a0 = T5[(t0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
471              T7[(t2>>> 8)&0xFF] ^ T8[(t1     )&0xFF] ^ K[keyOffset++];
472         a1 = T5[(t1>>>24)     ] ^ T6[(t0>>>16)&0xFF] ^
473              T7[(t3>>> 8)&0xFF] ^ T8[(t2     )&0xFF] ^ K[keyOffset++];
474         a2 = T5[(t2>>>24)     ] ^ T6[(t1>>>16)&0xFF] ^
475              T7[(t0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
476         t3 = T5[(t3>>>24)     ] ^ T6[(t2>>>16)&0xFF] ^
477              T7[(t1>>> 8)&0xFF] ^ T8[(t0     )&0xFF] ^ K[keyOffset++];
478         t0 = T5[(a0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
479              T7[(a2>>> 8)&0xFF] ^ T8[(a1     )&0xFF] ^ K[keyOffset++];
480         t1 = T5[(a1>>>24)     ] ^ T6[(a0>>>16)&0xFF] ^
481              T7[(t3>>> 8)&0xFF] ^ T8[(a2     )&0xFF] ^ K[keyOffset++];
482         t2 = T5[(a2>>>24)     ] ^ T6[(a1>>>16)&0xFF] ^
483              T7[(a0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
484         t3 = T5[(t3>>>24)     ] ^ T6[(a2>>>16)&0xFF] ^
485              T7[(a1>>> 8)&0xFF] ^ T8[(a0     )&0xFF] ^ K[keyOffset++];
486         a0 = T5[(t0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
487              T7[(t2>>> 8)&0xFF] ^ T8[(t1     )&0xFF] ^ K[keyOffset++];
488         a1 = T5[(t1>>>24)     ] ^ T6[(t0>>>16)&0xFF] ^
489              T7[(t3>>> 8)&0xFF] ^ T8[(t2     )&0xFF] ^ K[keyOffset++];
490         a2 = T5[(t2>>>24)     ] ^ T6[(t1>>>16)&0xFF] ^
491              T7[(t0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
492         t3 = T5[(t3>>>24)     ] ^ T6[(t2>>>16)&0xFF] ^
493              T7[(t1>>> 8)&0xFF] ^ T8[(t0     )&0xFF] ^ K[keyOffset++];
494         t0 = T5[(a0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
495              T7[(a2>>> 8)&0xFF] ^ T8[(a1     )&0xFF] ^ K[keyOffset++];
496         t1 = T5[(a1>>>24)     ] ^ T6[(a0>>>16)&0xFF] ^
497              T7[(t3>>> 8)&0xFF] ^ T8[(a2     )&0xFF] ^ K[keyOffset++];
498         t2 = T5[(a2>>>24)     ] ^ T6[(a1>>>16)&0xFF] ^
499              T7[(a0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
500         t3 = T5[(t3>>>24)     ] ^ T6[(a2>>>16)&0xFF] ^
501              T7[(a1>>> 8)&0xFF] ^ T8[(a0     )&0xFF] ^ K[keyOffset++];
502         a0 = T5[(t0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
503              T7[(t2>>> 8)&0xFF] ^ T8[(t1     )&0xFF] ^ K[keyOffset++];
504         a1 = T5[(t1>>>24)     ] ^ T6[(t0>>>16)&0xFF] ^
505              T7[(t3>>> 8)&0xFF] ^ T8[(t2     )&0xFF] ^ K[keyOffset++];
506         a2 = T5[(t2>>>24)     ] ^ T6[(t1>>>16)&0xFF] ^
507              T7[(t0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
508         t3 = T5[(t3>>>24)     ] ^ T6[(t2>>>16)&0xFF] ^
509              T7[(t1>>> 8)&0xFF] ^ T8[(t0     )&0xFF] ^ K[keyOffset++];
510         t0 = T5[(a0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
511              T7[(a2>>> 8)&0xFF] ^ T8[(a1     )&0xFF] ^ K[keyOffset++];
512         t1 = T5[(a1>>>24)     ] ^ T6[(a0>>>16)&0xFF] ^
513              T7[(t3>>> 8)&0xFF] ^ T8[(a2     )&0xFF] ^ K[keyOffset++];
514         t2 = T5[(a2>>>24)     ] ^ T6[(a1>>>16)&0xFF] ^
515              T7[(a0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
516         t3 = T5[(t3>>>24)     ] ^ T6[(a2>>>16)&0xFF] ^
517              T7[(a1>>> 8)&0xFF] ^ T8[(a0     )&0xFF] ^ K[keyOffset++];
518         a0 = T5[(t0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
519              T7[(t2>>> 8)&0xFF] ^ T8[(t1     )&0xFF] ^ K[keyOffset++];
520         a1 = T5[(t1>>>24)     ] ^ T6[(t0>>>16)&0xFF] ^
521              T7[(t3>>> 8)&0xFF] ^ T8[(t2     )&0xFF] ^ K[keyOffset++];
522         a2 = T5[(t2>>>24)     ] ^ T6[(t1>>>16)&0xFF] ^
523              T7[(t0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
524         t3 = T5[(t3>>>24)     ] ^ T6[(t2>>>16)&0xFF] ^
525              T7[(t1>>> 8)&0xFF] ^ T8[(t0     )&0xFF] ^ K[keyOffset++];
526         t0 = T5[(a0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
527              T7[(a2>>> 8)&0xFF] ^ T8[(a1     )&0xFF] ^ K[keyOffset++];
528         t1 = T5[(a1>>>24)     ] ^ T6[(a0>>>16)&0xFF] ^
529              T7[(t3>>> 8)&0xFF] ^ T8[(a2     )&0xFF] ^ K[keyOffset++];
530         t2 = T5[(a2>>>24)     ] ^ T6[(a1>>>16)&0xFF] ^
531              T7[(a0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
532         t3 = T5[(t3>>>24)     ] ^ T6[(a2>>>16)&0xFF] ^
533              T7[(a1>>> 8)&0xFF] ^ T8[(a0     )&0xFF] ^ K[keyOffset++];
534         a0 = T5[(t0>>>24)     ] ^ T6[(t3>>>16)&0xFF] ^
535              T7[(t2>>> 8)&0xFF] ^ T8[(t1     )&0xFF] ^ K[keyOffset++];
536         a1 = T5[(t1>>>24)     ] ^ T6[(t0>>>16)&0xFF] ^
537              T7[(t3>>> 8)&0xFF] ^ T8[(t2     )&0xFF] ^ K[keyOffset++];
538         a2 = T5[(t2>>>24)     ] ^ T6[(t1>>>16)&0xFF] ^
539              T7[(t0>>> 8)&0xFF] ^ T8[(t3     )&0xFF] ^ K[keyOffset++];
540         t3 = T5[(t3>>>24)     ] ^ T6[(t2>>>16)&0xFF] ^
541              T7[(t1>>> 8)&0xFF] ^ T8[(t0     )&0xFF] ^ K[keyOffset++];
542 
543         t1 = K[0];
544         out[outOffset++] = (byte)(Si[(a0 >>> 24)       ] ^ (t1 >>> 24));
545         out[outOffset++] = (byte)(Si[(t3 >>> 16) & 0xFF] ^ (t1 >>> 16));
546         out[outOffset++] = (byte)(Si[(a2 >>>  8) & 0xFF] ^ (t1 >>>  8));
547         out[outOffset++] = (byte)(Si[(a1       ) & 0xFF] ^ (t1       ));
548         t1 = K[1];
549         out[outOffset++] = (byte)(Si[(a1 >>> 24)       ] ^ (t1 >>> 24));
550         out[outOffset++] = (byte)(Si[(a0 >>> 16) & 0xFF] ^ (t1 >>> 16));
551         out[outOffset++] = (byte)(Si[(t3 >>>  8) & 0xFF] ^ (t1 >>>  8));
552         out[outOffset++] = (byte)(Si[(a2       ) & 0xFF] ^ (t1       ));
553         t1 = K[2];
554         out[outOffset++] = (byte)(Si[(a2 >>> 24)       ] ^ (t1 >>> 24));
555         out[outOffset++] = (byte)(Si[(a1 >>> 16) & 0xFF] ^ (t1 >>> 16));
556         out[outOffset++] = (byte)(Si[(a0 >>>  8) & 0xFF] ^ (t1 >>>  8));
557         out[outOffset++] = (byte)(Si[(t3       ) & 0xFF] ^ (t1       ));
558         t1 = K[3];
559         out[outOffset++] = (byte)(Si[(t3 >>> 24)       ] ^ (t1 >>> 24));
560         out[outOffset++] = (byte)(Si[(a2 >>> 16) & 0xFF] ^ (t1 >>> 16));
561         out[outOffset++] = (byte)(Si[(a1 >>>  8) & 0xFF] ^ (t1 >>>  8));
562         out[outOffset  ] = (byte)(Si[(a0       ) & 0xFF] ^ (t1       ));
563     }
564 
565 
566     /**
567      * Expand a user-supplied key material into a session key.
568      *
569      * @param key The 128/192/256-bit user-key to use.
570      * @exception InvalidKeyException  If the key is invalid.
571      */
572     private static Object[] makeKey(byte[] k) throws InvalidKeyException {
573         if (k == null) {
574             throw new InvalidKeyException("Empty key");
575         }
576         if (!isKeySizeValid(k.length)) {
577              throw new InvalidKeyException("Invalid AES key length: " +
578                                            k.length + " bytes");
579         }
580         int ROUNDS          = getRounds(k.length);
581         int ROUND_KEY_COUNT = (ROUNDS + 1) * 4;
582 
583         int BC = 4;
584         int[][] Ke = new int[ROUNDS + 1][4]; // encryption round keys
585         int[][] Kd = new int[ROUNDS + 1][4]; // decryption round keys
586 
587         int KC = k.length/4; // keylen in 32-bit elements
588 
589         int[] tk = new int[KC];
590         int i, j;
591 
592         // copy user material bytes into temporary ints
593         for (i = 0, j = 0; i < KC; i++, j+=4) {
594             tk[i] = (k[j]       ) << 24 |
595                     (k[j+1] & 0xFF) << 16 |
596                     (k[j+2] & 0xFF) <<  8 |
597                     (k[j+3] & 0xFF);
598         }
599 
600         // copy values into round key arrays
601         int t = 0;
602         for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) {
603             Ke[t / 4][t % 4] = tk[j];
604             Kd[ROUNDS - (t / 4)][t % 4] = tk[j];
605         }
606         int tt, rconpointer = 0;
607         while (t < ROUND_KEY_COUNT) {
608             // extrapolate using phi (the round key evolution function)
609             tt = tk[KC - 1];
610             tk[0] ^= (S[(tt >>> 16) & 0xFF]       ) << 24 ^
611                      (S[(tt >>>  8) & 0xFF] & 0xFF) << 16 ^
612                      (S[(tt       ) & 0xFF] & 0xFF) <<  8 ^
613                      (S[(tt >>> 24)       ] & 0xFF)       ^
614                      (rcon[rconpointer++]         ) << 24;
615             if (KC != 8)
616                 for (i = 1, j = 0; i < KC; i++, j++) tk[i] ^= tk[j];
617             else {
618                 for (i = 1, j = 0; i < KC / 2; i++, j++) tk[i] ^= tk[j];
619                 tt = tk[KC / 2 - 1];
620                 tk[KC / 2] ^= (S[(tt       ) & 0xFF] & 0xFF)       ^
621                               (S[(tt >>>  8) & 0xFF] & 0xFF) <<  8 ^
622                               (S[(tt >>> 16) & 0xFF] & 0xFF) << 16 ^
623                               (S[(tt >>> 24)       ]       ) << 24;
624                 for (j = KC / 2, i = j + 1; i < KC; i++, j++) tk[i] ^= tk[j];
625             }
626             // copy values into round key arrays
627             for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) {
628                 Ke[t / 4][t % 4] = tk[j];
629                 Kd[ROUNDS - (t / 4)][t % 4] = tk[j];
630             }
631         }
632         for (int r = 1; r < ROUNDS; r++) {
633             // inverse MixColumn where needed
634             for (j = 0; j < BC; j++) {
635                 tt = Kd[r][j];
636                 Kd[r][j] = U1[(tt >>> 24) & 0xFF] ^
637                            U2[(tt >>> 16) & 0xFF] ^
638                            U3[(tt >>>  8) & 0xFF] ^
639                            U4[ tt         & 0xFF];
640             }
641         }
642         // assemble the encryption (Ke) and decryption (Kd) round keys into
643         // one sessionKey object
644         Object[] result = new Object[] {Ke, Kd};
645         return result;
646     }
647 
648 
649     /**
650      * Return The number of rounds for a given Rijndael keysize.
651      *
652      * @param keySize  The size of the user key material in bytes.
653      *                 MUST be one of (16, 24, 32).
654      * @return         The number of rounds.
655      */
656     private static int getRounds(int keySize) {
657         return (keySize >> 2) + 6;
658     }
659 }